//////////////////////////////////////////////////////////////////////////////////
//                                                                              //
//  This file is part of the buola project (https://code.google.com/p/buola/).  //
//                                                                              //
//  Copyright(c) 2007-2012 Xavi Gratal                                          //
//  gratal AT gmail DOT com                                                     //
//                                                                              //
//  Buola is free software: you can redistribute it and/or modify               //
//  it under the terms of the GNU General Public License as published by        //
//  the Free Software Foundation, either version 3 of the License, or           //
//  (at your option) any later version.                                         //
//                                                                              //
//  Buola is distributed in the hope that it will be useful,                    //
//  but WITHOUT ANY WARRANTY; without even the implied warranty of              //
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               //
//  GNU General Public License for more details.                                //
//                                                                              //
//  You should have received a copy of the GNU General Public License           //
//  along with buola.  If not, see <http://www.gnu.org/licenses/>.              //
//                                                                              //
//////////////////////////////////////////////////////////////////////////////////

#include <buola/buola.h>

#include <buola/io/cfilefilter.h>
#include <buola/io/cfile.h>

#include <buola/io/glob.h>
#include <buola/io/filesystem.h>
#include <buola/io.h>

namespace buola { namespace io {

CFileFilter::~CFileFilter()
{
}

bool CFileFilter::CheckFile(const CFile &pFile)
{
    return CheckURI(pFile.URI());
}

bool CFileFilter::CheckURI(const CURI &pURI)
{
    return CheckName(pURI.Name());
}

bool CFileFilter::CheckName(const std::string& /*pName*/)
{
    return true;
}

CFlagsFileFilter::~CFlagsFileFilter()
{
}

bool CFlagsFileFilter::CheckFile(const CFile &pFile)
{
    if(pFile.IsLink())
    {
        io::CURI lTarget=pFile.GetTarget();
        if(!exists(lTarget))
            return (mFlags&BROKENLINKS);
        msg_info() << "target " << lTarget << "\n";
        if(lTarget==pFile.URI()) return true;
        return CheckFile(CFile(lTarget));
    }

    if((mFlags&NOFILES)&&!pFile.IsFolder())
    {
        return false;
    }
    if((mFlags&NOFOLDERS)&&pFile.IsFolder())
    {
        return false;
    }
    return CheckName(pFile.URI().Name());
}

bool CFlagsFileFilter::CheckName(const std::string &pName)
{
    if(pName[0]=='.')
    {
        if(pName.length()==1||(pName.length()==2&&pName[1]=='.'))
        {
            if(!(mFlags&RELATIVES))
                return false;
        }
        else if(!(mFlags&HIDDEN))
            return false;
    }

    return true;
}

CRegexFileFilter::CRegexFileFilter(const std::string &pRegExp,
                                const std::string &pName)
    : CFileFilter(pName)
{
    mRegExps.push_back(pRegExp);
}

CRegexFileFilter::~CRegexFileFilter()
{
}

void CRegexFileFilter::AddRegExp(const std::string &pRegExp)
{
    mRegExps.push_back(pRegExp);
}

bool CRegexFileFilter::CheckName(const std::string &pName)
{
    for(int i=0;i<mRegExps.size();i++)
    {
        if(io::glob_match(pName,mRegExps[i])) return true;
    }

    return false;
}

COrFileFilter::COrFileFilter(PFileFilter p1,PFileFilter p2,
                                    const std::string &pName)
    : CFileFilter(pName),m1(p1),m2(p2)
{
}

bool COrFileFilter::CheckFile(const CFile &pFile)
{
    return (m1->CheckFile(pFile)||m2->CheckFile(pFile));
}

bool COrFileFilter::CheckURI(const CURI &pURI)
{
    return (m1->CheckURI(pURI)||m2->CheckURI(pURI));
}

bool COrFileFilter::CheckName(const std::string &pName)
{
    return (m1->CheckName(pName)||m2->CheckName(pName));
}

CAndFileFilter::CAndFileFilter(PFileFilter p1,PFileFilter p2,
                                    const std::string &pName)
    : CFileFilter(pName),m1(p1),m2(p2)
{
}

bool CAndFileFilter::CheckFile(const CFile &pFile)
{
    return (m1->CheckFile(pFile)&&m2->CheckFile(pFile));
}

bool CAndFileFilter::CheckURI(const CURI &pURI)
{
    return (m1->CheckURI(pURI)&&m2->CheckURI(pURI));
}

bool CAndFileFilter::CheckName(const std::string &pName)
{
    return (m1->CheckName(pName)&&m2->CheckName(pName));
}


/*namespace io*/ } /*namespace buola*/ }
